#include "yamlHandler.h"
#include "log.h"

/**
 * @msg: 返回字符串中某个单词 以空格为间隔
 * @param {std::string src, int index（索引）} 
 * @return: std::string
 */
std::string peekString(std::string src, int index)
{
    std::string res;
        int count = 0, temp = 0;
        for(int j = 0; j < src.length(); j++)
        {
            char c = src[j];
            if(c == ' ' || (j + 1) == src.length())
            {
                if(src[j + 1] == ' ')
                    continue;
                if(count == index)
                {
                    if((j + 1) == src.length()){
                        res = src.substr(temp, j - temp + 1);
                        while(res[res.size() - 1] == ' ')
                            res = res.substr(0, res.size() - 1);
                    }
                    else{
                        res = src.substr(temp, j - temp);
                        while(res[res.size() - 1] == ' ')
                            res = res.substr(0, res.size() - 1);
                    }
                    return res;
                }
                else
                {
                    temp = j + 1;
                    count++;
                }
            }
        }
}

bool YamlHandler::loadFile(std::string _path)
{
    this->path = _path;
    std::ofstream outfile;
    outfile.open(this->path, std::ios::in);
    if(outfile.is_open())
        outfile.close();
    else{
        LOG::logPrint("file: " + this->path + " does not exist, creat new", LOG::WARNING);
        outfile.open(this->path, std::ios::out);
        outfile.close();
    }
    this->node = YAML::LoadFile(_path);
}

bool YamlHandler::dump()
{
    if(!this->path.empty())
    {
        std::fstream outfile;
        outfile.open(path, std::fstream::out | std::ios_base::trunc);
        YAML::Emitter emitter;
        emitter << this->node;
        outfile << emitter.c_str();
        outfile.close();
        return true;
    }
    else
        return false;
}

bool YamlHandler::copyTemp(std::string srcFilename, std::string dstFilename)
{
    std::ifstream l_infile;
	std::ofstream l_outfile;
    std::string temp;
	l_infile.open(srcFilename, std::ios::in);
	l_outfile.open(dstFilename, std::ios::trunc | std::ios::out);
	if (!l_infile.is_open() || !l_outfile.is_open())
	{
		return false;
	}
	while (!l_infile.eof())
	{
		std::getline(l_infile, temp, '\n');
		if(temp.size() > 0)
			l_outfile << temp << '\n';
	}
	l_infile.close();
	l_outfile.close();
	return true;
}

std::string YamlHandler::read(std::string lable1, std::string lable2)
{
    std::string res;
    if(lable2 != "")
    {
        res = this->node[lable1][lable2].as<std::string>();
    }
    else
    {
        res = this->node[lable1].as<std::string>();
    }
    return res;
}

std::string YamlHandler::readList(int num, std::string lable)
{
    return this->node[num][lable].as<std::string>();
}

bool YamlHandler::writeList(int num, std::string lable, std::string content)
{
    this->node[num][lable] = content;
    this->dump();
}

int YamlHandler::lines()
{
    int _lines = 0;
    std::string temp;
	std::ifstream l_infile;
	l_infile.open(this->path, std::ios::in);
    if(!l_infile.is_open())
        return 0;
	while (std::getline(l_infile, temp, '\n'))
		_lines++;
    l_infile.close();
	return _lines;
}

bool YamlHandler::deleteOneLine(int row)
{
    this->copyTemp(this->path, "./temp");
    std::ifstream l_infile;
	std::ofstream l_outfile;
    l_infile.open("./temp", std::ios::in);
	l_outfile.open(this->path, std::ios::out | std::ios::trunc);
    int pointer = 0;
    std::string temp;
	while (!l_infile.eof())
	{
		std::getline(l_infile, temp);
		if (pointer != row)
		{
			if (temp.size() > 0)
				l_outfile << temp << std::endl;
		}
		pointer++;
	}
	l_infile.close();
	l_outfile.close();
	std::remove("./temp");
	return true;
}

bool YamlHandler::deleteOneMap(int index)
{
    for(int i = index * lines_per_map; i < lines_per_map * (index + 1); i++)
    {
        this->deleteOneLine(index * lines_per_map);
    }
    return false;
}

std::string YamlHandler::currentPath()
{
    return this->path;
}

int YamlHandler::linesPerMap()
{
    return this->lines_per_map;
}

int YamlHandler::numofMap()
{
    return this->lines()/this->lines_per_map;
}